﻿using System;
using System.Collections.Generic;
using System.Linq;
using com.cruxomatic.BusinessFacades;
using com.cruxomatic.configuration;
using com.cruxomatic.configuration.FeatureManager;
using com.cruxomatic.contracts.Plugins;
using com.cruxomatic.views.Administration;
using com.cruxomatic.views.Enums;
using com.cruxomatic.DTOs;
using com.cruxomatic.logging;
using com.cruxomatic.logging.Enums;
using com.cruxomatic.exceptions;
using com.cruxomatic.security;

namespace com.cruxomatic.controllers.Administration
{
    public class ManageCompaniesController
    {
        IManageCompanies _view = null;
        public ManageCompaniesController(IManageCompanies view)
        {
            _view = view;
        }

        public void InitView(bool IsPostBack)
        {
            if (!IsPostBack)
            {
                SwitchToListMode();
            }
        }

        public void OpenCompany(int CompanyID)
        {
            IFeatureManager featureManager = FeatureManagerFactory.GetFeatureManager();
            _view.IsMasterLocationsSupported = featureManager.IsFeatureSupported("MasterLocations");
            ICruxSecurityManager cruxSecurityManager = CruxSecurityManagerFactory.GetSecurityManager();
            CompanyTypeFacade companyTypeFacade = new CompanyTypeFacade();
            CompanyInformation companyInformation = cruxSecurityManager.GetCompany(CompanyID);
            MasterLocationFacade facade = new MasterLocationFacade();
            List<MasterLocationInformation> selectedlocations = facade.GetMasterLocationsByCompany(CompanyID);
            List<MasterLocationInformation> allocations = facade.GetAllMasterLocation();
            allocations.RemoveAll(p => selectedlocations.Select(x => x.MasterLocationID).Contains(p.MasterLocationID));
            _view.SelectedMasterLocations = selectedlocations;
            _view.AllMasterLocations = allocations;

            _view.AllowedCompanyTypes = companyTypeFacade.GetAllCompanyTypes();
            _view.CurrentCompany = companyInformation;
            if (CompanyID > 0)
                _view.IsEditCompanyNameSupported = featureManager.IsFeatureSupported("EditOrganizationName");
            else
                _view.IsEditCompanyNameSupported = true;
            _view.ErrorDetails = null;
            _view.FormMode = FormMode.AddEdit;

        }

        public void CreateCompany()
        {
            OpenCompany(0);
        }

        public void SaveCompany()
        {
            try
            {
                CompanyFacade companyFacade = new CompanyFacade();
                SessionData session = new SessionData();
                companyFacade.SaveCompany(_view.CurrentCompany, session.CurrentUser.CompanyID);
                SwitchToListMode();
            }
            catch (CruxDatabaseException ex)
            {
                ApplicationLogger.LogApplicationMessage(
                    ex.Message, ApplicationLogType.Database, ex.StackTrace);
                _view.ErrorDetails = CruxApplicationErrorManager.GetApplicationError(ex.ErrorNameOrCode, ex.Message);
            }
            catch (Exception ex)
            {
                ApplicationLogger.LogApplicationMessage(
                    ex.Message, ApplicationLogType.Database, ex.StackTrace);
                _view.ErrorDetails = CruxApplicationErrorManager.GetApplicationError("101", ex.Message);
            }

        }

        public void SwitchToListMode()
        {
            IFeatureManager featureManager = FeatureManagerFactory.GetFeatureManager();
            ICruxSecurityManager securityManager = CruxSecurityManagerFactory.GetSecurityManager();
            _view.ErrorDetails = null;
            _view.CurrentCompany = new CompanyInformation();
            
            _view.IsEditCompanySupported = featureManager.IsFeatureSupported("EditCompany");
            SessionData sessiondata = new SessionData();
            UserInformation currentuser = sessiondata.CurrentUser;
            bool isUserGlobalAdministrator = securityManager.IsUserGlobalAdministrator(currentuser);
            bool isUserSuperAdminiistrator = securityManager.IsUserSuperAdministrator(currentuser);
            bool isUserLocalAdministrator = securityManager.IsUserAdministrator(currentuser);
            _view.IsAddCompanySupported = featureManager.IsFeatureSupported("AddCompany") 
                && (isUserSuperAdminiistrator || isUserGlobalAdministrator);

            if (isUserSuperAdminiistrator)
            {
                _view.Companies = securityManager.GetAllCompanies();   
            }
            else if (isUserGlobalAdministrator)
            {
                _view.Companies = securityManager.GetAllManagableCompanies(currentuser); ;
            }
            else if (isUserLocalAdministrator)
            {
                _view.Companies = securityManager.GetCompaniesForUser(currentuser.UserID);
            }
            
            _view.FormMode = FormMode.List;
        }

        public void CancelAddEdit()
        {
            SwitchToListMode();
        }

        public void DeleteCompany(int CompanyID)
        {

            try
            {
                CompanyFacade facade = new CompanyFacade();
                ICruxSecurityManager securityManager = CruxSecurityManagerFactory.GetSecurityManager();
                CompanyInformation compInformation = securityManager.GetCompany(CompanyID);
                IProcessor<CompanyInformation> plugObject = (IProcessor<CompanyInformation>)CruxConfigurationManager.GetProcessor("CompanyProcessor");
                if (plugObject != null)
                {
                    plugObject.FirePreprocessAction(compInformation);
                }
                facade.DeleteCompany(CompanyID);
                SwitchToListMode();
            }
            catch (CruxDatabaseException ex)
            {
                ApplicationLogger.LogApplicationMessage(
                    ex.Message, ApplicationLogType.Database, ex.StackTrace);
                _view.ErrorDetails = CruxApplicationErrorManager.GetApplicationError(ex.ErrorNameOrCode, ex.Message);
            }
            catch (Exception ex)
            {
                ApplicationLogger.LogApplicationMessage(
                    ex.Message, ApplicationLogType.Database, ex.StackTrace);
                _view.ErrorDetails = CruxApplicationErrorManager.GetApplicationError("101", ex.Message);
            }
        }

        public void OpenCompanyAdministrationView(int CompanyID)
        {
            NavigationController.OpenView("ManageCompany", CompanyID);
        }

        public void RedirectToPreviousPage()
        {
            NavigationController.OpenView("Administration");
        }
    }
}
